package org.jeecg.modules.appuser.util;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.security.MD5Encoder;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class PayUtils {

    public static String pay(String product_type,Double price, int num, String return_url,String trade_order_id) {

        Double total_fee = price*num;
        String url = "https://api.xunhupay.com/payment/do.html";
        Map<String, String> sortParams = new HashMap<>();
        sortParams.put("version", "1.1");
        sortParams.put("plugins", "");//可选。备注字段，可以传入一些备注数据，回调时原样返回
        sortParams.put("appid", "201906130019");
        sortParams.put("trade_order_id", trade_order_id);
        sortParams.put("total_fee", String.valueOf(total_fee));
        sortParams.put("title", "积分购买"+product_type);
        sortParams.put("time", new Date().getTime()/1000+"");
        sortParams.put("callback_url","http://www.shenqikoudai.com/shopIndex/#/integralTopUp");
        //必填。用户支付成功后，我们服务器会主动发送一个post消息到这个网址(注意：当前接口内，SESSION内容无效)
        //http://www.shenqikoudai.com:9000/netmall/app/person/api/returnPay
        sortParams.put("notify_url", "http://www.shenqikoudai.com:9000/netmall/app/person/api/returnPay");
        //可选。用户支付成功后，我们会让用户浏览器自动跳转到这个网址
        sortParams.put("return_url", return_url);
        sortParams.put("nonce_str",  RandomUtil.randomNumbers(10));//必填。作用：1.避免服务器页面缓存，2.防止安全密钥被猜测出来
        String hash= createSign(sortParams,"8a6dd9a0a19166537e60301406e94e8f");
        System.out.println("开始调三方接口---》》》"+hash);
        sortParams.put("hash", hash);
        System.out.println("开始调三方接口");
        System.out.println("JSON.toJSONString(sortParams)-->"+JSON.toJSONString(sortParams));
        String response = HttpUtil.post("https://api.xunhupay.com/payment/do.html", JSON.toJSONString(sortParams));
        System.out.println("调三方接口结束"+response);
        com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(response);
        if (jsonObject != null) {
            Integer errorcode = jsonObject.getInteger("errcode");
            String errmsg = jsonObject.getString("errmsg");
            if (errorcode == 0 && StringUtils.equals(errmsg, "success!")) {
                System.out.println("返回跳转连接成功");
                System.out.println(trade_order_id+"---订单已存入");
                System.out.println( jsonObject.getString(""));
                return jsonObject.getString("url");
            }
        }
        return "";
    }

    public static String createSign(Map<String, String> params, String privateKey) {
        StringBuilder sb = new StringBuilder();
        // 将参数以参数名的字典升序排序
        Map<String, String> sortParams = sortMapByKey(params);
        // 遍历排序的字典,并拼接"key=value"格式
        for (Map.Entry<String, String> entry : sortParams.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue().trim();
            if (StringUtils.isNotEmpty(value)) {
                sb.append("&").append(key).append("=").append(value);
            }
        }

        String stringA = sb.toString().replaceFirst("&", "");
        System.out.println("stringA: " + stringA);
//		byte[] stringSignTemp = (stringA + privateKey).getBytes();
        String stringSignTemp = stringA + privateKey;
        String signValue = "";
        try {
            signValue = encode(stringSignTemp);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return signValue;
    }

    public static Map<String, String> sortMapByKey(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, String> sortMap = new TreeMap(new MapKeyComparator());
        sortMap.putAll(map);
        return sortMap;
    }

    public static class MapKeyComparator implements Comparator<String> {
        public int compare(String str1, String str2) {
            return str1.compareTo(str2);
        }
    }

    public static String encode(String string) throws Exception {
        String s = null;
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f' };// 用来将字节转换成16进制表示的字符
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(string.getBytes());
            byte tmp[] = md.digest();// MD5 的计算结果是一个 128 位的长整数，
            // 用字节表示就是 16 个字节
            char str[] = new char[16 * 2];// 每个字节用 16 进制表示的话，使用两个字符， 所以表示成 16
            // 进制需要 32 个字符
            int k = 0;// 表示转换结果中对应的字符位置
            for (int i = 0; i < 16; i++) {// 从第一个字节开始，对 MD5 的每一个字节// 转换成 16
                // 进制字符的转换
                byte byte0 = tmp[i];// 取第 i 个字节
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];// 取字节中高 4 位的数字转换,// >>>
                // 为逻辑右移，将符号位一起右移
                str[k++] = hexDigits[byte0 & 0xf];// 取字节中低 4 位的数字转换
            }
            s = new String(str);// 换后的结果转换为字符串
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return s;
    }
}
